home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Archive / Graphics / QuickDraw GX / GX->PostScript Sample / GXToPostScript / Font Handler / FontHandlerVariations.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  10.6 KB  |  421 lines  |  [TEXT/MPS ]

  1. /*
  2.      File:        FontHandlerVariations.c
  3.  
  4.      Contains:    QuickDraw GX to PostScript conversion code.
  5.                          File contains code to deal with font variation snapshots
  6.  
  7.      Version:    Technology:    Quickdraw GX 1.1.x
  8.       
  9.      Copyright:    © 1991-1997 by Apple Computer, Inc., all rights reserved.
  10. */
  11.  
  12. #include <Collections.h>
  13. #include <MacMemory.h>
  14. #include <GXExceptions.h>
  15. #include "GXToPSBuildConfig.h"
  16. #include "GXPrintingUniverse.h"
  17. #include <Collections.h>
  18. #include "GXGraphics.h"
  19. #include "FontDatabase.h"
  20. #include "FontHandler.h"
  21. #include "FontHandlerPrivate.h"
  22. #include "FontHandlerVariations.h"
  23.  
  24. #ifdef resumeLabel
  25.     #undef resumeLabel
  26. #endif
  27. #define resumeLabel(exception)
  28.  
  29.  
  30. /****************************
  31.     FDBEqualVariations:
  32.     
  33.     Test two varations for equality
  34.     Assumes both variations have same
  35.     number of axes.
  36.     
  37.     num:                number of axes
  38.     v1:                    pointer to 1st coordinates
  39.     v2:                    pointer to 2nd coordinates
  40.     
  41. ******************************/
  42. Boolean    FHEqualVariations(long num, gxFontVariation* v1, gxFontVariation* v2)
  43.     {
  44.         register short        idx;    
  45.     
  46.         for (idx = num - 1; idx >= 0; --idx) {
  47.  
  48.             if ( (v1->name != v2->name) || (v1->value != v2->value))
  49.                 return(false);
  50.  
  51.             ++v1;
  52.             ++v2;
  53.             
  54.         }//end for
  55.         
  56.         return(true);    
  57.     
  58.     }//FHEqualVariations
  59.     
  60.     
  61.  
  62.  
  63. //<FF>
  64. /**********************************
  65.  
  66.     FHCountSnapshots:
  67.     
  68.     Function counts the number of snapshot
  69.     fonts for the document.
  70.     
  71. ************************************/
  72. long FHCountSnapshots(TFontHandlerHdl hFHRec)
  73.     {
  74.         long            n;
  75.         
  76.         n = CountCollectionItems((*hFHRec)->snapShots);            // how many items in snapshot collection.
  77.                 
  78.         return(n);        
  79.     
  80.     }//FHCountSnapshots
  81.  
  82.  
  83.  
  84. /***********************************
  85.  
  86.     FHGetIndexedSnapshot:
  87.     
  88.     Retrieves the snapshot id by index in the collection.
  89.     
  90. ************************************/
  91. OSErr FHGetIndexedSnapshot(TFontHandlerHdl hFHRec, long index, fhFont *theFont)
  92.     {
  93.         OSErr            status;
  94.         
  95.         status = GetIndexedCollectionItemInfo((*hFHRec)->snapShots,
  96.                                                                                     index,
  97.                                                                                     nil,                                    // We don't care about the real font reference.
  98.                                                                                     (long*)theFont,                // the snapshot is cached in the id in addition to the data.
  99.                                                                                     nil,
  100.                                                                                     nil);
  101.         
  102.         ncheck(status);
  103.         return(status);    
  104.     
  105.     }//FHGetIndexedSnapshot
  106.     
  107.  
  108.  
  109. //<FF>
  110. /*************************************
  111.  
  112.     Function: FHAddFontSnapShot
  113.     
  114.         Function adds a snapshot to the snapshot collection.
  115.         Returns the snapshot id.
  116.     
  117.             hFHRec:                        the font handler context handle
  118.             theFont:                    the font in question.
  119.             dbIndex:                    index of bit array in database.
  120.             snapshotID:                The snapshot id to use.
  121.     
  122. ***************************************/
  123. OSErr FHAddFontSnapShot(TFontHandlerHdl hFHRec, gxFont theFont, long dbIndex, fhFont *snapshotID)
  124.     {
  125.         OSErr                        status = noErr;
  126.         TFontHandlerPtr    pFHRec;
  127.         TFHSnapShot            snapShotRec;
  128.         Collection            snapShots;                    // the collection of snapshots.
  129.         long                        nSnapshots, idx;
  130.     
  131.         pFHRec = *hFHRec;
  132.         
  133.         snapShots = pFHRec->snapShots;
  134.     
  135.         /** Make sure it is not already in the database **/
  136.  
  137.         nSnapshots = CountTaggedCollectionItems(snapShots, (CollectionTag)theFont);
  138.         
  139.         for (idx = 1; idx <= nSnapshots; ++idx) {
  140.         
  141.             status = GetTaggedCollectionItem(snapShots, (CollectionTag)theFont, idx, nil, &snapShotRec);
  142.             nrequire(status, failed_GetItem);
  143.             
  144.             if (snapShotRec.dbIndex == dbIndex) {
  145.                 
  146.                 *snapshotID = snapShotRec.snapShotFont;
  147.                 break;
  148.                 
  149.             }//end if
  150.  
  151.         }//end for
  152.         
  153.         
  154.         /* If it wasn't already in the collection, add it */
  155.         
  156.         if (idx > nSnapshots) {
  157.     
  158.             *snapshotID = (fhFont)(*hFHRec)->nextSnapShot;
  159.             snapShotRec.snapShotFont = *snapshotID;
  160.             snapShotRec.dbIndex = dbIndex;
  161.             snapShotRec.theFont = theFont;
  162.             
  163.             status = AddCollectionItem(snapShots, 
  164.                                                                     (CollectionTag)theFont,                                 // the snapshot id will be collection tag
  165.                                                                     (long)*snapshotID,                                            // the gx font will be the ID
  166.                                                                     sizeof(TFHSnapShot), &snapShotRec);
  167.             nrequire(status, failed_AddItem);
  168.             
  169.             (*hFHRec)->nextSnapShot += 1;                    // increment the next available snapshot id.
  170.         
  171.         }//end if
  172.         
  173. failed_AddItem:
  174. failed_GetItem:
  175.  
  176.         return(status);
  177.  
  178.     }//FHAddFontSnapShot
  179.  
  180.  
  181.  
  182. //<FF>
  183. /****************************************
  184.  
  185.     Function: FHGetSnapShotFont
  186.     
  187.     Function returns the real font ID from a snapshot font id.
  188.     
  189.     hFHRec:                    The font handler context handle.
  190.     snapShotFont:        snap shot font to look up.
  191.     dbIndex:                if not nil, the variation/bit pair index is returned here.
  192.     
  193.     the gxFont ID is reuturned, nil means snapshot is invalid.
  194.     
  195. ******************************************/
  196. gxFont FHGetSnapShotFont(TFontHandlerHdl hFHRec, fhFont snapShotFont, long *dbIndex)
  197.     {
  198.         long                            idx;    
  199.         gxFont                        theFont;
  200.         TFHSnapShot                snapshotRec;
  201.         long                            n;
  202.         Collection                snapshots;
  203.         fhFont                        theSnapshot;
  204.         
  205.         snapshots = (*hFHRec)->snapShots;
  206.         n = CountCollectionItems(snapshots);
  207.         
  208.         /** The snapshot ID is stored as the id in the collection item, search for a match **/
  209.  
  210.         for (idx = 1; idx <= n; ++idx) {
  211.         
  212.             GetIndexedCollectionItemInfo(snapshots, idx, 
  213.                     (CollectionTag*)&theFont,                                                // the collection tag is the real font
  214.                     (long*)&theSnapshot,                                                        // The id is the snapshot ID
  215.                     nil, nil);
  216.                     
  217.             if (theSnapshot == snapShotFont)
  218.                 break;
  219.         
  220.         }//end for
  221.     
  222.         if (idx > n) {
  223.         
  224.             theFont = nil;                // couldn't find a match.
  225.             
  226.         } else if (dbIndex != nil) {
  227.         
  228.             GetIndexedCollectionItem(snapshots, idx, nil, &snapshotRec);
  229.             *dbIndex = snapshotRec.dbIndex;
  230.         
  231.         }//end if
  232.             
  233.         return(theFont);
  234.     
  235.     }//FHGetSnapShotFont
  236.  
  237.     
  238. //<FF>
  239. /********************************************
  240.  
  241.     Function:  FontHandlerGetStyleFont
  242.     
  243.     Function is wrapper for real call.  Returns an fhFont
  244.     instead of gxFont
  245.     
  246.     context:            A font handler context.
  247.     theStyle:            The style to retrieve the snapshot font from.
  248.     theFont:            (returned)  This is the font snapshot ID
  249.     
  250. **********************************************/
  251. OSErr _FontHandlerGetStyleFont(TFontHandlerContext context, gxStyle theStyle, fhFont *theFont)
  252.     {
  253.         OSErr                            status = noErr;
  254.         long                            nVariations;                        // Number of variations for the style.
  255.         gxFontVariation        *theVariations;
  256.         gxFontVariation        *dbVariations;
  257.         long                            nSnapshots;                            // Number of snapshots in the database.
  258.         long                            idx;
  259.         TFHSnapShot                snapShotRec;
  260.         TFontDbase                fontDbase;
  261.         Collection                snapShots;
  262.         TFontHandlerPtr        pFHRec;
  263.         Handle                        h = nil;
  264.         gxFont                        theGXFont;
  265.     
  266.         pFHRec = *(TFontHandlerHdl)context;
  267.         fontDbase = pFHRec->docDbase;
  268.         snapShots = pFHRec->snapShots;
  269.  
  270.         theGXFont = FHgxGetStyleFont(theStyle);
  271.  
  272.         nSnapshots = CountTaggedCollectionItems(snapShots, (CollectionTag)theGXFont);
  273.         
  274.         if (nSnapshots > 0) {
  275.         
  276.             /* Get the variations from the style */
  277.             
  278.             nVariations = GXGetStyleFontVariationSuite(theStyle, nil);
  279.             
  280.             if (nVariations > 0) {
  281.             
  282.                 status = FHSetWorkHandleSize((TFontHandlerHdl)context, nVariations * sizeof(gxFontVariation), 5, &h);
  283.                 nrequire(status, failed_workhandle);
  284.                 HLock(h);
  285.                 theVariations = (gxFontVariation*)*h;
  286.                 GXGetStyleFontVariationSuite(theStyle, theVariations);
  287.                 
  288.             }//end if
  289.             
  290.             /* Now find a match for the variations in the database */
  291.                             
  292.             for (idx = 1; idx <= nSnapshots; ++idx) {
  293.             
  294.                 status = GetTaggedCollectionItem(snapShots, (CollectionTag)theGXFont, idx, nil, &snapShotRec);            
  295.                 nrequire(status, failed_getitem);
  296.  
  297.                 /** If the font doesn't need snapshots then return the snapshot for the main bit array **/
  298.                 if (snapShotRec.dbIndex == eMainBits) {
  299.  
  300.                     /* The only way we could have a snapshot with dbIndex == eMainBits is if font doesn't require snapshots */
  301.                     *theFont = snapShotRec.snapShotFont;
  302.                     break;
  303.  
  304.                 } else {
  305.  
  306.                     /* Compare the style's variations against the ones in the font database for this snapshot */
  307.                     
  308.                     status = FontDbaseGetGlyphBits(fontDbase, theGXFont, snapShotRec.dbIndex, nil, &dbVariations);
  309.                     nrequire(status, failed_getbits);
  310.                     
  311.                     /* warning, the font database is not locked so memory better not move during the comparison */
  312.                     
  313.                     if (FHEqualVariations(nVariations, dbVariations, theVariations)) {
  314.  
  315.                         *theFont = snapShotRec.snapShotFont;
  316.                         break;
  317.                     
  318.                     }//end if
  319.                     
  320.                 }//end if
  321.                     
  322.             }//end for
  323.             
  324.         } else {
  325.         
  326.             /** If there were no entries matching the style's gxFont and variations, return nil for the fhFont **/
  327.  
  328.             *theFont = nil;
  329.             status = noErr;
  330.             
  331.         }//end if
  332.         
  333. failed_getbits:
  334. failed_getitem:
  335.  
  336.         if (h != nil)
  337.             FHReleaseWorkspace((TFontHandlerHdl)context, 5);
  338.  
  339. failed_workhandle:
  340.  
  341.         check(*theFont);    /* should only happen if font/variation combo was not in database (extensions can cause this) */
  342.  
  343.         return(status);
  344.     
  345.     }//FontHandlerGetStyleFont
  346.  
  347.  
  348.  
  349. //<FF>
  350. /**************************************************
  351.  
  352.     Function: FontHandlerGetStyleFontVariations
  353.  
  354.     Function returns the variations from a style
  355.     based on the snapshot that the style uses.
  356.     
  357.     If the snapshot uses the main bit array, thus
  358.     meaning the gxFont did not require snapshots,
  359.     then the variations are returned.
  360.     
  361.     Otherwise, no variations are returned
  362.         
  363.     context:            A font handler context.
  364.     theStyle:            The style to retrieve the snapshot font from.
  365.     count:                (returned)  The number of axes.
  366.     variations:        (returned)    The variation data.
  367.     
  368. ****************************************************/
  369.  
  370. OSErr _FontHandlerGetStyleFontVariations(TFontHandlerContext context, gxStyle theStyle, long *count, gxFontVariation variations[])
  371.     {
  372.         OSErr                            status;
  373.         fhFont                        theSnapShot;    
  374.         gxFont                        theFont;
  375.         TFHSnapShot                snapShotRec;
  376.         
  377.         /* Get the snapshot id */
  378.         
  379.         status = _FontHandlerGetStyleFont(context, theStyle, &theSnapShot);
  380.         nrequire(status, failed_snapshot);
  381.  
  382.         /* Get the snapshot data */
  383.         
  384.         theFont = FHgxGetStyleFont(theStyle);                    // the real font helps us get into the collection without searching.
  385.  
  386.         status = GetCollectionItem( (*(TFontHandlerHdl)context)->snapShots,
  387.                                                                 (CollectionTag)theFont,
  388.                                                                 (long)theSnapShot,
  389.                                                                 nil,
  390.                                                                 &snapShotRec);        
  391.         nrequire(status, failed_GetItem);
  392.         
  393.         /******
  394.             If the snapshot points to the main bits, then that means font
  395.             does not require snapshots, return real variation info from style
  396.         ******/
  397.         if (snapShotRec.dbIndex == eMainBits) {
  398.  
  399.                 *count = GXGetStyleFontVariationSuite(theStyle, variations);
  400.         
  401.         } else {
  402.         
  403.                 /* if the style requires a real snapshot, then to the callers point of view there are no variations */
  404.         
  405.                 *count = 0;
  406.         
  407.         }//end if
  408.         
  409. failed_GetItem:
  410.     #if DEBUGLEVEL > 1
  411.         if (status == collectionItemNotFoundErr)
  412.             dprintf(notrace, "Wierd, asking for variations that are not in database.  Shouldn't happen");
  413.             
  414.     #endif
  415.     
  416. failed_snapshot:
  417.  
  418.         return(status);
  419.     
  420.     }//FontHandlerGetStyleVariations 
  421.